/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.webos.java.passwords;

import org.json.JSONObject;
import org.webos.java.base.ApplicationType;
import org.webos.java.base.Application;
import org.webos.java.base.Session;
import org.webos.java.base.SessionStateListener;
import org.webos.java.base.hsqldb.HSQLDBConnection;
import org.webos.java.base.hsqldb.migration.DBDefinition;
import org.webos.java.base.hsqldb.migration.RowDefinition;
import org.webos.java.base.hsqldb.migration.TableDefinition;
import org.webos.java.base.workspace.FrameHolder;
import org.webos.java.base.workspace.Splitter;
import org.webos.java.base.workspace.Workspace;
import org.webos.java.root.Log;
/**
 *
 * @author kostya
 */

@ApplicationType(code="passwords", description="Secure password manager",
    jsClass="passwords.Application", name="Password manager", version="0.1",
    errorCode=1019, icon="passwords_icns passwords_icn_main")
public class PasswordManager extends Application{

    private String password = null;
    HSQLDBConnection connection = new HSQLDBConnection("/.passwords/db", "sa", "");
    CategoriesFrame categories = null;
    PasswordsFrame grid = null;
    Workspace ws = new Workspace(this, "main");

    public PasswordManager(Session aSession) {
        super(aSession);
        aSession.addSessionStateListener(new SessionStateListener() {
            public void sessionOnline() {
                lockPassword();
            }
            public void sessionOffline() {
            }
        });
    }

    @Override
    public void initialize() {
        if(!setupDB()){
            sendError(1001, "Can't initialize database. Application terminated");
            stopApplication(null);
        }
        ws.setCaption("Password manager");
        grid = new PasswordsFrame(this, ws);
        categories = new CategoriesFrame(this, ws);
        Splitter sp = new Splitter("sp0", true, 0.3);
        ws.setItem(sp);
        sp.setLeftItem(new FrameHolder(sp, "fh0", categories));
        sp.setRightItem(new FrameHolder(sp, "fh1", grid));
        addWorkspace(ws);
        addFrame(categories);
        addFrame(grid);
        showWorkspace(ws);
    }

    @Override
    public void terminate() {
        JSONObject settings = getOptionObject("options");
        if(categories.controller.getSelected()!=null){
            settings.putOpt("folder", categories.controller.getSelected().getId());
            setOption("options", settings.toString());
        }
        connection.close();
    }


    private boolean setupDB(){
        try {
            if(!connection.openConnection(getSession(), false))
                return false;
            DBDefinition dbd = new DBDefinition();
            TableDefinition cat = new TableDefinition("CATEGORIES");
            RowDefinition idCat = new RowDefinition("ID", "INTEGER", true);
            cat.addRow(idCat);
            cat.addRow(new RowDefinition("NAME", "VARCHAR(255)"));
            cat.addRow(new RowDefinition("ICON", "VARCHAR(100)", "''"));
            dbd.addTable(cat);
            TableDefinition pass = new TableDefinition("PASSWORDS");
            pass.addRow(new RowDefinition("ID", "INTEGER", true));
            pass.addRow(new RowDefinition("NAME", "VARCHAR(255)", "''"));
            pass.addRow(new RowDefinition("URL", "VARCHAR(255)", "''"));
            pass.addRow(new RowDefinition("NOTES", "VARCHAR(1023)", "''"));
            pass.addRow(new RowDefinition("USERNAME", "VARCHAR(255)", "''"));
            pass.addRow(new RowDefinition("PASSWORD", "VARCHAR(255)", "''"));
            pass.addRow(new RowDefinition("CREATE_DATE", "TIMESTAMP"));
            pass.addRow(new RowDefinition("ID_CAT", "INTEGER", idCat));
            dbd.addTable(pass);
            if(dbd.migrateDB(connection.getConnection()))
                return true;
        } catch (Throwable t) {
            Log.error(this, "Exception thrown: " + t.getMessage());
            t.printStackTrace();
        }
        return false;
    }

    void lockPassword(){
        password = null;
        grid.passwordStateChanged(false);
    }

    String getPassword(){
        if(password==null){
            //Show password dialog
            String storedPassword = getSecret("master_password", null);
            password = new MasterPassword(this).getPassword(storedPassword);
            if(password!=null){
                grid.passwordStateChanged(true);
                setSecret("master_password", password);
            }
        }
        return password;
    }
}
